package com.lemon.core.validator.configuration;

import com.lemon.core.validator.annotation.EnableFastFailValidator;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 * 参数校验配置
 * 直接使用{@link org.springframework.context.annotation.Configuration}将开启全局快速失败
 * 配合使用{@link EnableFastFailValidator}灵活配置
 *
 * @author pan
 * @since 2019-01-27
 */
public class ValidatorConfiguration {

    /**
     * 校验@RequestBody时，采用快速失败模式
     */
    @Bean
    public Validator validator(AutowireCapableBeanFactory autowireCapableBeanFactory) {
        // false：普通模式(会校验完所有的属性，然后返回所有的验证失败信息)
        // true：快速失败返回模式(只要有一个验证失败，则直接返回，不再进行后续参数校验)
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(true) // failFast=true 不校验所有参数，只要出现校验失败情况直接返回，不再进行后续参数校验
            .constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
            .buildValidatorFactory();

        return validatorFactory.getValidator();
    }

    /**
     * 校验@RequestParam时，采用快速失败模式
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        // 设置validator
        postProcessor.setValidator(validator);
        return postProcessor;
    }
}
